#region Using Statements

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

#endregion

namespace _1942
{
    /// <summary>
    /// This is a game component that implements a Animated Sprite.
    /// </summary>
    public class Sprite : DrawableGameComponent
    {
        #region Variables

        protected int activeFrame;
        private readonly Texture2D texture;
        private List<Rectangle> frames = new List<Rectangle>();

        private Vector2 _position;
        protected TimeSpan elapsedTime = TimeSpan.Zero;
        protected Rectangle currentFrame;
        protected long frameDelay;
        protected SpriteBatch sbBatch;

        //Makes sure that the exploding sound olny plays once
        protected bool explodingSoundplayed = false;
        //Sound
        protected AudioLibrary audio;

        // tmp vars need to offset in sprite-map.
        // 4px beginning of sprite-map
        public const int START_OFFSET = 5;

        #endregion

        #region Constructors

        /// <summary>
        /// Default construtor
        /// </summary>
        /// <param name="game">The game object</param>
        /// <param name="theTexture">Texture that contains the sprite frames</param>
        public Sprite(Game game, ref Texture2D theTexture)
            : base(game)
        {
            // Get the audio library
            audio = (AudioLibrary)Game.Services.GetService(typeof(AudioLibrary));
            texture = theTexture;
            activeFrame = 0;
        }

        #endregion


        #region Methods

        protected override void UnloadContent()
        {
            this.texture.Dispose();

            base.UnloadContent();
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to 
        /// before starting to run.  This is where it can query for any required
        ///  services and load content.
        /// </summary>
        public override void Initialize()
        {
            // Get the current spritebatch
            sbBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            elapsedTime += gameTime.ElapsedGameTime;

            // it's time to a next frame?
            if (elapsedTime > TimeSpan.FromMilliseconds(frameDelay))
            {
                elapsedTime -= TimeSpan.FromMilliseconds(frameDelay);
                activeFrame++;
                if (activeFrame == frames.Count)
                {
                    activeFrame = 0;
                }
                // Get the current frame
                currentFrame = frames[activeFrame];
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// Draw the sprite.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            sbBatch.Draw(texture, Position, currentFrame, Color.White);

            base.Draw(gameTime);
        }

        #endregion

        #region Properties
        
        /// <summary>
        /// List with the frames of the animation
        /// </summary>
        public List<Rectangle> Frames
        {
            get { return frames; }
            set { frames = value; }
        }

        public Vector2 Position 
        {
            get { return _position; } 
            set { _position = value; }
        }

        public float PositionX
        {
            get { return _position.X; }
            set { _position.X = value; }
        }

        public float PositionY
        {
            get { return _position.Y; }
            set { _position.Y = value; }
        }

        // Implement fudgefactor for collisions?
        public Rectangle getRect
        {
            get { return new Rectangle((int)Position.X, (int)Position.Y, Frames[0].Width, Frames[0].Height); }
        }

        #endregion

    }
}